import { Request, Response, NextFunction } from 'express';
import { prisma } from '../../config/database';
import { logger } from '../../utils/logger';
import { BaseController } from '../../utils/autoBind';
import { ResponseUtils } from '../../utils/responseUtils';
import { BUSINESS_ERROR_CODES, VALIDATION_ERROR_CODES } from '../../utils/errorCodes';

export class RoleController extends BaseController {
  // 获取角色列表
  async getRoles(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { page = 1, limit = 20, search = '', status } = req.query;
      const pageNum = parseInt(page as string);
      const limitNum = parseInt(limit as string);
      const skip = (pageNum - 1) * limitNum;

      // 构建查询条件
      const where: any = {};
      
      if (search) {
        where.OR = [
          { name: { contains: search as string } },
          { description: { contains: search as string } }
        ];
      }

      if (status) {
        where.status = status;
      }

      // 查询角色列表
      const [roles, total] = await Promise.all([
        prisma.role.findMany({
          where,
          select: {
            id: true,
            name: true,
            description: true,
            status: true,
            createdAt: true,
            updatedAt: true,
            _count: {
              select: {
                userRoles: true,
                rolePermissions: true
              }
            }
          },
          skip,
          take: limitNum,
          orderBy: { createdAt: 'desc' }
        }),
        prisma.role.count({ where })
      ]);

      // 计算分页信息
      ResponseUtils.paginated(res, roles, total, pageNum, limitNum);
    } catch (error) {
      next(error);
    }
  }

  // 获取角色详情
  async getRoleById(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { id } = req.params;
      const roleId = parseInt(id);

      if (isNaN(roleId)) {
        ResponseUtils.sendError(res, VALIDATION_ERROR_CODES.FIELD_TYPE_ERROR, '无效的角色ID');
        return;
      }

      const role = await prisma.role.findUnique({
        where: { id: roleId },
        select: {
          id: true,
          name: true,
          description: true,
          status: true,
          createdAt: true,
          updatedAt: true,
          rolePermissions: {
            include: {
              permission: {
                select: {
                  id: true,
                  name: true,
                  code: true,
                  module: true
                }
              }
            }
          },
          userRoles: {
            include: {
              user: {
                select: {
                  id: true,
                  username: true,
                  realName: true,
                  email: true
                }
              }
            }
          }
        }
      });

      if (!role) {
        ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.ROLE_NOT_FOUND, '角色不存在');
        return;
      }

      ResponseUtils.success(res, { role });
    } catch (error) {
      next(error);
    }
  }

  // 创建角色
  async createRole(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { name, description, status = 'ACTIVE', permissionIds } = req.body;

      // 验证必需字段
      if (!name) {
        ResponseUtils.sendError(res, VALIDATION_ERROR_CODES.REQUIRED_FIELD_MISSING, '角色名称为必填项');
        return;
      }

      // 检查角色名称是否已存在
      const existingRole = await prisma.role.findUnique({
        where: { name }
      });

      if (existingRole) {
        ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.ROLE_ALREADY_EXISTS, '角色名称已存在');
        return;
      }

      // 创建角色
      const role = await prisma.role.create({
        data: {
          name,
          description,
          status
        },
        select: {
          id: true,
          name: true,
          description: true,
          status: true,
          createdAt: true
        }
      });

      // 分配权限
      if (permissionIds && Array.isArray(permissionIds) && permissionIds.length > 0) {
        const rolePermissions = permissionIds.map(permissionId => ({
          roleId: role.id,
          permissionId: parseInt(permissionId)
        }));

        await prisma.rolePermission.createMany({
          data: rolePermissions
        });
      }

      logger.info(`角色创建成功: ${role.name} (ID: ${role.id})`);
      ResponseUtils.created(res, { role });
    } catch (error) {
      next(error);
    }
  }

  // 更新角色
  async updateRole(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { id } = req.params;
      const { name, description, status, permissionIds } = req.body;
      const roleId = parseInt(id);

      if (isNaN(roleId)) {
        ResponseUtils.sendError(res, VALIDATION_ERROR_CODES.FIELD_TYPE_ERROR, '无效的角色ID');
        return;
      }

      // 检查角色是否存在
      const existingRole = await prisma.role.findUnique({
        where: { id: roleId }
      });

      if (!existingRole) {
        ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.ROLE_NOT_FOUND, '角色不存在');
        return;
      }

      // 检查角色名称是否被其他角色使用
      if (name && name !== existingRole.name) {
        const duplicateRole = await prisma.role.findUnique({
          where: { name }
        });

        if (duplicateRole) {
          ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.ROLE_ALREADY_EXISTS, '角色名称已存在');
          return;
        }
      }

      // 更新角色基本信息
      const updateData: any = {};
      if (name !== undefined) updateData.name = name;
      if (description !== undefined) updateData.description = description;
      if (status !== undefined) updateData.status = status;

      const role = await prisma.role.update({
        where: { id: roleId },
        data: updateData,
        select: {
          id: true,
          name: true,
          description: true,
          status: true,
          updatedAt: true
        }
      });

      // 更新权限分配
      if (permissionIds !== undefined) {
        // 删除现有权限
        await prisma.rolePermission.deleteMany({
          where: { roleId }
        });

        // 添加新权限
        if (Array.isArray(permissionIds) && permissionIds.length > 0) {
          const rolePermissions = permissionIds.map(permissionId => ({
            roleId,
            permissionId: parseInt(permissionId)
          }));

          await prisma.rolePermission.createMany({
            data: rolePermissions
          });
        }
      }

      logger.info(`角色更新成功: ${role.name} (ID: ${role.id})`);
      ResponseUtils.updated(res, { role });
    } catch (error) {
      next(error);
    }
  }

  // 删除角色
  async deleteRole(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { id } = req.params;
      const roleId = parseInt(id);

      if (isNaN(roleId)) {
        ResponseUtils.sendError(res, VALIDATION_ERROR_CODES.FIELD_TYPE_ERROR, '无效的角色ID');
        return;
      }

      // 检查角色是否存在
      const existingRole = await prisma.role.findUnique({
        where: { id: roleId }
      });

      if (!existingRole) {
        ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.ROLE_NOT_FOUND, '角色不存在');
        return;
      }

      // 检查是否有用户使用此角色
      const userCount = await prisma.userRole.count({
        where: { roleId }
      });

      if (userCount > 0) {
        ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.ROLE_IN_USE, '该角色正在被用户使用，无法删除');
        return;
      }

      // 删除角色权限关联
      await prisma.rolePermission.deleteMany({
        where: { roleId }
      });

      // 删除角色
      await prisma.role.delete({
        where: { id: roleId }
      });

      logger.info(`角色删除成功: ${existingRole.name} (ID: ${roleId})`);
      ResponseUtils.deleted(res);
    } catch (error) {
      next(error);
    }
  }

  // 获取角色统计信息
  async getRoleStats(_req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      // 获取角色总数
      const totalRoles = await prisma.role.count();

      // 获取活跃角色数
      const activeRoles = await prisma.role.count({
        where: { status: 'ACTIVE' }
      });

      // 获取非活跃角色数
      const inactiveRoles = await prisma.role.count({
        where: { status: 'INACTIVE' }
      });

      // 获取有权限的角色数
      const rolesWithPermissions = await prisma.role.count({
        where: {
          rolePermissions: {
            some: {}
          }
        }
      });

      // 获取有用户的角色数
      const rolesWithUsers = await prisma.role.count({
        where: {
          userRoles: {
            some: {}
          }
        }
      });

      // 获取最常用的角色
      const topRoles = await prisma.role.findMany({
        select: {
          id: true,
          name: true,
          description: true,
          status: true,
          _count: {
            select: {
              userRoles: true,
              rolePermissions: true
            }
          }
        },
        orderBy: {
          userRoles: {
            _count: 'desc'
          }
        },
        take: 10
      });

      // 获取权限分布
      const permissionDistribution = await prisma.role.groupBy({
        by: ['status'],
        _count: {
          id: true
        }
      });

      const stats = {
        total: totalRoles,
        active: activeRoles,
        inactive: inactiveRoles,
        withPermissions: rolesWithPermissions,
        withUsers: rolesWithUsers,
        topRoles: topRoles.map(role => ({
          id: role.id,
          name: role.name,
          description: role.description,
          status: role.status,
          userCount: role._count.userRoles,
          permissionCount: role._count.rolePermissions
        })),
        distribution: permissionDistribution.map(item => ({
          status: item.status,
          count: item._count.id
        }))
      };

      ResponseUtils.success(res, stats);
    } catch (error) {
      next(error);
    }
  }

  // 分配权限给角色
  async assignPermissions(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { id } = req.params;
      const { permissionIds } = req.body;
      const roleId = parseInt(id);

      if (isNaN(roleId)) {
        ResponseUtils.sendError(res, VALIDATION_ERROR_CODES.FIELD_TYPE_ERROR, '无效的角色ID');
        return;
      }

      if (!Array.isArray(permissionIds)) {
        ResponseUtils.sendError(res, VALIDATION_ERROR_CODES.FIELD_TYPE_ERROR, '权限ID列表格式错误');
        return;
      }

      // 检查角色是否存在
      const existingRole = await prisma.role.findUnique({
        where: { id: roleId }
      });

      if (!existingRole) {
        ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.ROLE_NOT_FOUND, '角色不存在');
        return;
      }

      // 验证权限是否存在
      if (permissionIds.length > 0) {
        const validPermissions = await prisma.permission.findMany({
          where: {
            id: {
              in: permissionIds.map(id => parseInt(id))
            }
          }
        });

        if (validPermissions.length !== permissionIds.length) {
          ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.PERMISSION_NOT_FOUND, '部分权限不存在');
          return;
        }
      }

      // 删除现有权限分配
      await prisma.rolePermission.deleteMany({
        where: { roleId }
      });

      // 添加新的权限分配
      if (permissionIds.length > 0) {
        const rolePermissions = permissionIds.map(permissionId => ({
          roleId,
          permissionId: parseInt(permissionId)
        }));

        await prisma.rolePermission.createMany({
          data: rolePermissions
        });
      }

      logger.info(`角色权限分配成功: ${existingRole.name} (ID: ${roleId})`);
      ResponseUtils.success(res, { message: '权限分配成功' });
    } catch (error) {
      next(error);
    }
  }

  // 获取角色权限列表
  async getRolePermissions(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { id } = req.params;
      const roleId = parseInt(id);

      if (isNaN(roleId)) {
        ResponseUtils.sendError(res, VALIDATION_ERROR_CODES.FIELD_TYPE_ERROR, '无效的角色ID');
        return;
      }

      // 检查角色是否存在
      const existingRole = await prisma.role.findUnique({
        where: { id: roleId }
      });

      if (!existingRole) {
        ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.ROLE_NOT_FOUND, '角色不存在');
        return;
      }

      // 获取角色权限
      const rolePermissions = await prisma.rolePermission.findMany({
        where: { roleId },
        include: {
          permission: {
            select: {
              id: true,
              name: true,
              code: true,
              description: true,
              module: true
            }
          }
        }
      });

      const permissions = rolePermissions.map(rp => rp.permission);

      ResponseUtils.success(res, { permissions });
    } catch (error) {
      next(error);
    }
  }
} 